home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1843 / 1843.xpi / content / firebug / bindings.xml < prev    next >
Extensible Markup Language  |  2010-01-08  |  44KB  |  1,151 lines

  1. <?xml version="1.0"?>
  2.  
  3. <!DOCTYPE window [
  4. <!ENTITY % firebugDTD SYSTEM "chrome://firebug/locale/firebug.dtd">
  5. %firebugDTD;
  6. ]>
  7.  
  8. <bindings xmlns="http://www.mozilla.org/xbl"
  9.     xmlns:xbl="http://www.mozilla.org/xbl"
  10.     xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  11.  
  12. <binding id="initializer">
  13.     <implementation>
  14.         <destructor><![CDATA[
  15.            FirebugChrome.shutdown();
  16.         ]]></destructor>
  17.     </implementation>
  18. </binding>
  19.  
  20. <binding id="panelBar">
  21.  
  22.     <!-- The XUL structure for the panel bar is specified in the XUL source
  23.          inside each "panelBar" element.  This allows us to have panel bars
  24.          with substantially different layous, including the ability to embed
  25.          one panel bar within another - albeit at some cost in maintainability.
  26.     -->
  27.     <content>
  28.         <children/>
  29.     </content>
  30.  
  31.     <implementation>
  32.         <constructor><![CDATA[
  33.             this.tabBox = this.getChildElement("tabBox");
  34.             this.deck = this.getChildElement("deck");
  35.             this.browser = this.getChildElement("browser");
  36.             this.panelTabs = this.getChildElement("panelTabs");
  37.             this.tabMap = {};
  38.  
  39.             // We initialize Firebug from here instead of from the onload event because
  40.             // we need to make sure it is initialized before the browser starts loading
  41.             // the home page
  42.             try
  43.             {
  44.                 if(FirebugChrome.panelBarReady(this))
  45.                 {
  46.                 }
  47.             }
  48.             catch (e)
  49.             {
  50.                 dump("bindings panelBar ctor FAILs: "+ e+"\n");
  51.                 dump("window.top "+window.top.location+" window.opener: "+window.opener+"\n");
  52.             }
  53.         ]]></constructor>
  54.  
  55.         <method name="getChildElement">
  56.             <parameter name="id"/>
  57.             <body><![CDATA[
  58.                 // Construct a unique ID from the panel bar ID and the child element ID,
  59.                 // for example: "panelBar1-panelTabs".  This allows us to define children
  60.                 // in the XUL source, which in turn allows us to have panel bars with
  61.                 // substantially different layouts.
  62.                 return document.getElementById(this.id + "-" + id);
  63.             ]]></body>
  64.         </method>
  65.  
  66.         <method name="createTab">
  67.             <parameter name="panelType"/>
  68.             <body><![CDATA[
  69.             var tab = document.createElement("panelTab");
  70.             tab.panelType = panelType;
  71.  
  72.             var title = Firebug.getPanelTitle(panelType);
  73.             tab.setAttribute("label", title);
  74.  
  75.             return this.tabMap[panelType.prototype.name] = tab;
  76.             ]]></body>
  77.         </method>
  78.  
  79.         <method name="addTab">
  80.             <parameter name="panelType"/>
  81.             <body><![CDATA[
  82.             var tab = this.createTab(panelType);
  83.             this.panelTabs.appendChild(tab);
  84.             ]]></body>
  85.         </method>
  86.  
  87.         <method name="updatePanels">
  88.             <parameter name="panelTypes"/>
  89.             <body><![CDATA[
  90.                 this.tabMap = {};
  91.  
  92.                 // Replace tabs at the same position if type has changed
  93.                 var i = 0;
  94.                 var tab = this.panelTabs.firstChild;
  95.                 for (; i < panelTypes.length && tab; tab = tab.nextSibling)
  96.                 {
  97.                     var panelType = panelTypes[i++];
  98.                     if (tab.panelType.prototype.name != panelType.prototype.name)
  99.                     {
  100.                         var newTab = this.createTab(panelType);
  101.                         this.panelTabs.replaceChild(newTab, tab);
  102.                         tab = newTab;
  103.                     }
  104.                     else
  105.                         this.tabMap[panelType.prototype.name] = tab;
  106.                 }
  107.  
  108.                 // Remove old tabs after the last panel
  109.                 while (tab)
  110.                 {
  111.                     var nextTab = tab.nextSibling;
  112.                     this.panelTabs.removeChild(tab);
  113.                     tab = nextTab;
  114.                 }
  115.  
  116.                 // Insert new tabs after the last old tab
  117.                 for (; i < panelTypes.length; ++i)
  118.                 {
  119.                     var panelType = panelTypes[i];
  120.                     var newTab = this.createTab(panelType);
  121.                     this.panelTabs.appendChild(newTab);
  122.                 }
  123.             ]]></body>
  124.         </method>
  125.  
  126.         <method name="selectTab">
  127.             <parameter name="tab"/>
  128.             <body><![CDATA[
  129.                 var panelName = tab ? tab.panelType.prototype.name : null;
  130.                 if (panelName && !tab.panelType.prototype.parentPanel)
  131.                     Firebug.setPref(Firebug.prefDomain, "defaultPanelName", panelName);
  132.  
  133.                 this.selectPanel(panelName);
  134.             ]]></body>
  135.         </method>
  136.  
  137.         <method name="selectPanel">
  138.             <parameter name="panelName"/>
  139.             <parameter name="forceUpdate"/>
  140.             <parameter name="noRefresh"/>
  141.             <body><![CDATA[
  142.                 var tab = panelName ? this.tabMap[panelName] : null;
  143.                 var panelType = tab ? tab.panelType : null;
  144.  
  145.                 var panel = FirebugContext ? FirebugContext.getPanel(panelName) : null;
  146.  
  147.                 if (panel && (panel == this.selectedPanel) && !forceUpdate)
  148.                     return panel;
  149.  
  150.                 this.hideSelectedPanel();
  151.  
  152.                 if (!panel)
  153.                     this.tabBox.setAttribute("collapsed", "true");
  154.                 else
  155.                     this.tabBox.removeAttribute("collapsed");
  156.  
  157.                 if (this.selectedTab)
  158.                     this.selectedTab.selected = false;
  159.  
  160.                 this.selectedTab = tab;
  161.                 this.selectedPanel = panel;
  162.  
  163.                 if (tab)
  164.                 {
  165.                     tab.selected = true;
  166.                     if (Firebug.A11yModel && Firebug.A11yModel.isEnabled() && Firebug.A11yModel.tabFocused &&!forceUpdate)
  167.                         tab.focus();
  168.                 }
  169.  
  170.                 if (panel)
  171.                 {
  172.                     panel.panelBrowser = panel.browser ? panel.browser : this.browser;
  173.                     panel.panelBrowser.currentPanel = panel;
  174.                 }
  175.  
  176.                 if (!panel || panel.panelBrowser != this.browser)
  177.                     this.browser.currentPanel = null;
  178.  
  179.                 var ev = document.createEvent("Events");
  180.                 ev.initEvent("selectingPanel", true, false);
  181.                 this.dispatchEvent(ev);
  182.  
  183.                 if (panel)
  184.                 {
  185.                     var sel = this.browser.contentWindow.getSelection();
  186.                     if (sel)
  187.                         sel.removeAllRanges();
  188.  
  189.                     this.showSelectedPanel();  // sets active attribute true
  190.  
  191.                     if (!noRefresh && panel.needsRefresh)
  192.                     {
  193.                         delete panel.needsRefresh;
  194.                         panel.refresh();
  195.                     }
  196.  
  197.                     if (panel.browser)
  198.                     {
  199.                         if (panel.browser.parentNode != this.deck)
  200.                             this.deck.appendChild(panel.browser);
  201.  
  202.                         this.deck.selectedPanel = panel.browser;
  203.                     }
  204.                     else
  205.                         this.deck.selectedPanel = this.browser;
  206.                 }
  207.  
  208.                 var ev = document.createEvent("Events");
  209.                 ev.initEvent("selectPanel", true, false);
  210.                 this.dispatchEvent(ev);
  211.  
  212.                 return panel;
  213.             ]]></body>
  214.         </method>
  215.  
  216.         <method name="showSelectedPanel">
  217.             <body><![CDATA[
  218.                 var panel = this.selectedPanel;
  219.                 if (panel)
  220.                 {
  221.                     panel.visible = true;
  222.                     panel.panelNode.setAttribute("active", true);
  223.  
  224.                     var state = Firebug.getPanelState(panel);
  225.                     panel.show(state);
  226.  
  227.                     this.updateToolbarVisibility();
  228.                 }
  229.             ]]></body>
  230.         </method>
  231.  
  232.         <method name="updateToolbarVisibility">
  233.             <body><![CDATA[
  234.                 var noButtons = true;
  235.                 var toolbarInner = FBL.$("fbToolbarInner");
  236.                 var box = toolbarInner.firstChild;
  237.                 while (box)
  238.                 {
  239.                     var tagName = box.tagName.toLowerCase();
  240.                     var collapsed = box.getAttribute("collapsed");
  241.                     if (collapsed != "true")
  242.                     {
  243.                         if (tagName == "panelstatus" && !box.firstChild)
  244.                         {
  245.                             box = box.nextSibling;
  246.                             continue;
  247.                         }
  248.  
  249.                         noButtons = false;
  250.                         break;
  251.                     }
  252.  
  253.                     box = box.nextSibling;
  254.                 }
  255.  
  256.                 var toolbar = FBL.$("fbToolbox");
  257.                 FBL.collapse(toolbar, noButtons);
  258.             ]]></body>
  259.         </method>
  260.  
  261.         <method name="hideSelectedPanel">
  262.             <body><![CDATA[
  263.                 var oldPanel = this.selectedPanel;
  264.                 if (oldPanel)
  265.                 {
  266.                     var state = FBL.getPersistedState(FirebugContext, oldPanel.name);
  267.                     oldPanel.hide(state);
  268.  
  269.                     oldPanel.visible = false;  // xxxjjb Why three ways to un-show the panel?
  270.                     oldPanel.panelNode.removeAttribute("active");
  271.                 }
  272.             ]]></body>
  273.         </method>
  274.  
  275.         <method name="getTab">
  276.             <parameter name="panelName"/>
  277.             <body><![CDATA[
  278.                 return this.tabMap[panelName];
  279.             ]]></body>
  280.         </method>
  281.     </implementation>
  282.  
  283.     <handlers>
  284.         <handler event="mousedown" button="0"><![CDATA[
  285.             event.stopPropagation();
  286.             var tab = event.target;
  287.             for (; tab && !tab.panelType; tab = tab.parentNode);
  288.  
  289.             if (tab)
  290.             {
  291.                 // Select after a timeout to increase teh snappy
  292.                 setTimeout(FBL.bindFixed(function()
  293.                 {
  294.                     this.selectTab(tab);
  295.                 }, this));
  296.             }
  297.         ]]></handler>
  298.     </handlers>
  299. </binding>
  300.  
  301. <binding id="panelTab" display="xul:button">
  302.     <content>
  303.         <xul:image class="panelTab-left"/>
  304.         <xul:label class="panelTab-text" crop="right" flex="1"
  305.                    xbl:inherits="value=label,accesskey,crop,toolbarmode,buttonstyle,disabled"/>
  306.         <children includes="panelTabMenu"/>
  307.         <xul:image class="panelTab-right"/>
  308.     </content>
  309.     <implementation>
  310.         <constructor>
  311.         <![CDATA[
  312.             this.setAttribute('role', 'tab');
  313.             this.setAttribute('aria-haspopup', 'true');
  314.             if (!this.tabMenu)
  315.             {
  316.                 this.tabMenu = document.createElement("panelTabMenu");
  317.                 this.appendChild(this.tabMenu);
  318.             }
  319.             return this.tabMenu;
  320.         ]]>
  321.         </constructor>
  322.         <method name="setModule">
  323.             <parameter name="module"/>
  324.             <body><![CDATA[
  325.             // Make sure the property exists.
  326.             this.tabMenu.module = module ? module : null;
  327.             ]]></body>
  328.         </method>
  329.         <property name="selected">
  330.             <getter><![CDATA[
  331.                 return this.getAttribute("selected");
  332.             ]]></getter>
  333.             <setter><![CDATA[
  334.                 this.setAttribute("selected", val);
  335.                 this.tabMenu.updateVisibility();
  336.             ]]></setter>
  337.         </property>
  338.     </implementation>
  339. </binding>
  340.  
  341. <binding id="panelTabMenu" display="xul:button" extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
  342.     <content>
  343.         <xul:menupopup anonid="popup" />
  344.         <xul:image anonid="menuTarget" class="menuTarget"/>
  345.     </content>
  346.     <implementation>
  347.         <constructor>
  348.         <![CDATA[
  349.             this.setAttribute('role', 'menu');
  350.             this.popup = document.getAnonymousElementByAttribute(this, "anonid", "popup");
  351.         ]]>
  352.         </constructor>
  353.         <field name="value"/>
  354.         <field name="module"/>
  355.         <property name="selectedPanel">
  356.             <getter><![CDATA[
  357.                 var parentNode = this.parentNode;
  358.                 while (parentNode)
  359.                 {
  360.                     if (parentNode.hasOwnProperty("selectedPanel"))
  361.                         return parentNode.selectedPanel;
  362.                     parentNode = parentNode.parentNode;
  363.                 }
  364.                 return null;
  365.             ]]></getter>
  366.         </property>
  367.         <method name="onEnable">
  368.             <body><![CDATA[
  369.             if (this.module)
  370.                 this.module.setDefaultState(true);
  371.             ]]></body>
  372.         </method>
  373.         <method name="onDisable">
  374.             <body><![CDATA[
  375.             if (this.module)
  376.                 this.module.setDefaultState(false);
  377.             ]]></body>
  378.         </method>
  379.         <method name="optionMenu">
  380.             <parameter name="label"/>
  381.             <parameter name="checked"/>
  382.             <parameter name="command"/>
  383.             <body><![CDATA[
  384.             return {label: label, type: "radio", checked: checked,
  385.                 command: FBL.bindFixed(command, this)};
  386.             ]]></body>
  387.         </method>
  388.         <method name="updateVisibility">
  389.             <body><![CDATA[
  390.             // Hide the mini-menu (displaying panel's option) if following is true:
  391.             // 1) The panel isn't activable (this.module == null) and so there are
  392.             //    no enable/disable options.
  393.             // 2) The panel doesn't provide any additional options.
  394.             var panel = this.selectedPanel;
  395.             var panelItems = panel ? panel.getOptionsMenuItems(FirebugContext) : null;
  396.             if (!this.module && !(panelItems && panelItems.length))
  397.                 this.setAttribute("collapsed", "true");
  398.             ]]></body>
  399.         </method>
  400.     </implementation>
  401.     <handlers>
  402.         <handler event="mousedown" button="0"><![CDATA[
  403.             this.popup.showPopup(this, -1, -1, "popup", "bottomleft", "topleft");
  404.         ]]></handler>
  405.         <handler event="popupshowing"><![CDATA[
  406.             if (!this.selectedPanel)
  407.                 return false;
  408.  
  409.             var items = [];
  410.  
  411.             // Create menu items for activation. The module is set only for activable modules.
  412.             if (this.module)
  413.             {
  414.                 var enabled = this.module.isAlwaysEnabled();
  415.                 items.push(this.optionMenu("panel.Enabled", enabled, this.onEnable));
  416.                 items.push(this.optionMenu("panel.Disabled", !enabled, this.onDisable));
  417.             }
  418.  
  419.             // Get panel's option items.
  420.             var panelItems = this.selectedPanel.getOptionsMenuItems(FirebugContext);
  421.             if (!panelItems)
  422.                 return false;
  423.  
  424.             // If the module is disabled, gray out all the options.
  425.             if (!enabled && this.module)
  426.             {
  427.                 for (var i = 0; i < panelItems.length; i++)
  428.                     panelItems[i].disabled = true;
  429.             }
  430.  
  431.             if (panelItems.length > 0)
  432.                 items.push("-");
  433.  
  434.             var menu = FBL.extendArray(items, panelItems);
  435.             for (var i = 0; i < menu.length; ++i)
  436.                 FBL.createMenuItem(this.popup, menu[i]);
  437.  
  438.             return true;
  439.         ]]></handler>
  440.         <handler event="popuphidden"><![CDATA[
  441.             FBL.eraseNode(this.popup);
  442.         ]]></handler>
  443.     </handlers>
  444. </binding>
  445.  
  446. <binding id="panelStatus">
  447.     <implementation>
  448.         <method name="addItem">
  449.             <parameter name="label"/>
  450.             <parameter name="object"/>
  451.             <parameter name="rep"/>
  452.             <parameter name="separator"/>
  453.             <body><![CDATA[
  454.                 if (this.firstChild)
  455.                 {
  456.                     var box = document.createElement("hbox");  // extra box needed to fix alignment issue in Vista theme
  457.                     box.setAttribute('role', 'separator');
  458.                     box.setAttribute('align', 'center');
  459.                     var sep = document.createElement("label");
  460.                     sep.setAttribute("class", "panelStatusSeparator");
  461.                     sep.setAttribute("value", separator);
  462.                     sep.setAttribute('role', 'presentation');
  463.                     box.appendChild(sep);
  464.                     this.appendChild(box);
  465.                 }
  466.  
  467.                 var item = document.createElement("toolbarbutton");
  468.                 item.setAttribute("class", "panelStatusLabel");
  469.                 item.setAttribute("label", label);
  470.                 item.repObject = object;
  471.                 item.rep = rep;
  472.                 this.appendChild(item);
  473.                 return item;
  474.             ]]></body>
  475.         </method>
  476.  
  477.         <method name="clear">
  478.             <parameter name="tab"/>
  479.             <body><![CDATA[
  480.                 while (this.lastChild)
  481.                     this.removeChild(this.lastChild);
  482.             ]]></body>
  483.         </method>
  484.  
  485.         <method name="getItemByObject">
  486.             <parameter name="object"/>
  487.             <body><![CDATA[
  488.                 for (var item = this.lastChild; item; item = item.previousSibling)
  489.                 {
  490.                     if (item.rep)
  491.                     {
  492.                         var itemObject = item.rep.getRealObject(item.repObject, FirebugContext);
  493.                         if (itemObject == object)
  494.                             return item;
  495.                     }
  496.                 }
  497.             ]]></body>
  498.         </method>
  499.  
  500.         <method name="selectObject">
  501.             <parameter name="object"/>
  502.             <body><![CDATA[
  503.                 var item = this.getItemByObject(object);
  504.                 this.selectItem(item);
  505.             ]]></body>
  506.         </method>
  507.  
  508.         <method name="selectItem">
  509.             <parameter name="item"/>
  510.             <body><![CDATA[
  511.                 if (this.selectedItem)
  512.                     this.selectedItem.removeAttribute("selected");
  513.  
  514.                 this.selectedItem = item;
  515.  
  516.                 if (item)
  517.                 {
  518.                     item.setAttribute("selected", "true");
  519.  
  520.                     var ev = document.createEvent("Events");
  521.                     ev.initEvent("selectItem", true, false);
  522.                     this.dispatchEvent(ev);
  523.                 }
  524.             ]]></body>
  525.         </method>
  526.     </implementation>
  527.  
  528.     <handlers>
  529.         <handler event="command" ><![CDATA[
  530.             var object = Firebug.getRepObject(event.target);
  531.             if (object)
  532.             {
  533.                 var rep = Firebug.getRep(object);
  534.                 object = rep.getRealObject(object, FirebugContext);
  535.                 if (object)
  536.                 {
  537.                     this.selectObject(object);
  538.                     Firebug.chrome.select(object, null, null, true);
  539.                 }
  540.             }
  541.         ]]></handler>
  542.  
  543.         <handler event="mouseover"><![CDATA[
  544.             var object = Firebug.getRepObject(event.target);
  545.             if (object)
  546.             {
  547.                 var rep = Firebug.getRep(object);
  548.                 object = rep.getRealObject(object, FirebugContext);
  549.                 if (object)
  550.                     Firebug.Inspector.highlightObject(object, FirebugContext);
  551.             }
  552.         ]]></handler>
  553.  
  554.         <handler event="mouseout"><![CDATA[
  555.             Firebug.Inspector.highlightObject(null);
  556.         ]]></handler>
  557.     </handlers>
  558. </binding>
  559.  
  560. <binding id="panelFileList">
  561.  
  562.     <content popup="_child">
  563.         <xul:label class="toolbarbutton-text title" crop="right" flex="1"
  564.             xbl:inherits="value=title"/>
  565.         <xul:menupopup anonid="popup" position="after_start"/>
  566.         <children includes="observes|template|menupopup|tooltip"/>
  567.         <xul:image class="toolbarbutton-icon"
  568.             xbl:inherits="validate,src=image,toolbarmode,buttonstyle"/>
  569.         <xul:label class="toolbarbutton-text label" crop="right" flex="1"
  570.              xbl:inherits="value=label,accesskey,crop,toolbarmode,buttonstyle"/>
  571.         <xul:dropmarker type="menu" class="toolbarbutton-menu-dropmarker"
  572.             xbl:inherits="disabled,label"/>
  573.     </content>
  574.  
  575.     <resources>
  576.         <stylesheet src="chrome://global/skin/toolbarbutton.css"/>
  577.     </resources>
  578.  
  579.     <implementation>
  580.         <constructor><![CDATA[
  581.             this.popup = document.getAnonymousElementByAttribute(this, "anonid", "popup");
  582.             this._closed = true;
  583.         ]]></constructor>
  584.  
  585.         <property name="location">
  586.             <getter><![CDATA[
  587.                 if (FBTrace.DBG_LOCATIONS)
  588.                     FBTrace.sysout("location getter label:"+this.getAttribute('label')+" location: "+this.getAttribute('location'));
  589.                 return this.getAttribute("location");
  590.             ]]></getter>
  591.  
  592.             <setter><![CDATA[
  593.                 var locator = this.getLocator();
  594.  
  595.                 var fileName = null;
  596.                 if (!locator)
  597.                 {
  598.                     fileName = "no locator!";
  599.                 }
  600.                 else if (val)
  601.                 {
  602.                     var description = locator.getObjectDescription(val);
  603.                     fileName = (description.label?description.label:description.name);
  604.                 }
  605.                 else
  606.                     fileName = "(none)";
  607.  
  608.                 this.repObject = val;
  609.                 this.setAttribute("label", FBL.cropString(fileName, 80));
  610.                 this.setAttribute("location", val);
  611.                 if (FBTrace.DBG_LOCATIONS)
  612.                     FBTrace.sysout("location setter label:"+this.getAttribute('label')+" fileName: "+fileName+ " val: "+val);
  613.             ]]></setter>
  614.         </property>
  615.  
  616.         <method name="getLocator">
  617.             <body><![CDATA[
  618.                 if (!this.locator)  // XXXjjb this is complicated because the location list depends upon the current panel
  619.                 {
  620.                     var functionYieldingExpression = this.getAttribute("locationProvider");
  621.                     if (functionYieldingExpression && functionYieldingExpression.length > 0)
  622.                         this.locator = eval(functionYieldingExpression);
  623.                     else
  624.                     {
  625.                         var whichBinding = this.getAttribute("id");
  626.                         var msg = "ERROR: panelFileList "+whichBinding+" requires attribute \'locationProvider\', an expression yielding a function";
  627.                         FBTrace.sysout(msg);
  628.                         return null;
  629.                     }
  630.                 }
  631.                 // The locator needs
  632.                 //     getObjectDescription(object): return {path, name}
  633.                 //     getLocationList(), a list of objects that can be fed into getObjectDescription
  634.                 return this.locator(this);
  635.             ]]></body>
  636.         </method>
  637.  
  638.         <method name="showPopup">
  639.             <body><![CDATA[
  640.                 this.popup.showPopup(this, -1, -1, "popup", "bottomleft", "topleft");
  641.             ]]></body>
  642.         </method>
  643.  
  644.         <method name="selectObject">
  645.             <parameter name="object"/>
  646.             <body><![CDATA[
  647.                 this.repObject = object;
  648.  
  649.                 var ev = document.createEvent("Events");
  650.                 ev.initEvent("selectObject", true, false);
  651.                 this.dispatchEvent(ev);
  652.             ]]></body>
  653.         </method>
  654.  
  655.         <method name="enterActiveItem">
  656.             <body><![CDATA[
  657.                 for (var child = this.popup.firstChild; child; child = child.nextSibling)
  658.                 {
  659.                     if (child.getAttribute("_moz-menuactive") == "true")
  660.                     {
  661.                         this.location = child.repObject;
  662.                         this.selectObject(child.repObject);
  663.                         this.popup.hidePopup();
  664.                     }
  665.                 }
  666.             ]]></body>
  667.         </method>
  668.  
  669.         <method name="filterList">
  670.             <parameter name="substring"/>
  671.             <body><![CDATA[
  672.                 var firstMatch = null;
  673.                 var groupMatchCount = 0;
  674.                 for (var child = this.popup.lastChild; child; child = child.previousSibling)
  675.                 {
  676.                     if (child.localName == "menuitem")
  677.                     {
  678.                         var label = child.getAttribute("label").toLowerCase();
  679.                         child._searchMatch = label.indexOf(substring) != -1;
  680.                         if (child._searchMatch)
  681.                         {
  682.                             firstMatch = child;
  683.                             ++groupMatchCount;
  684.                         }
  685.                     }
  686.                     else
  687.                     {
  688.                         child._searchMatch = !!groupMatchCount;
  689.                         groupMatchCount = 0;
  690.                     }
  691.                 }
  692.  
  693.                 if (firstMatch)
  694.                 {
  695.                     for (var child = this.popup.firstChild; child; child = child.nextSibling)
  696.                     {
  697.                         child.hidden = !child._searchMatch;
  698.                         child.removeAttribute("_moz-menuactive");
  699.                     }
  700.  
  701.                     firstMatch.setAttribute("_moz-menuactive", "true");
  702.                 }
  703.             ]]></body>
  704.         </method>
  705.  
  706.         <method name="onKeyPress">
  707.             <parameter name="event"/>
  708.             <body><![CDATA[
  709.                 if (event.keyCode == 13) // Return
  710.                 {
  711.                     this.enterActiveItem();
  712.                     this.searchString = '';
  713.                 }
  714.                 else if (event.keyCode == 8) // Backspace
  715.                 {
  716.                     this.searchString = this.searchString.substr(0, this.searchString.length-1);
  717.                     this.filterList(this.searchString);
  718.                 }
  719.                 else if (event.charCode)
  720.                 {
  721.                     this.searchString += String.fromCharCode(event.charCode).toLowerCase();
  722.                     this.filterList(this.searchString);
  723.                 }
  724.                 else
  725.                     return;
  726.  
  727.                 Firebug.Search.displayOnly(this.searchString, FirebugContext);
  728.                 FBL.cancelEvent(event);
  729.             ]]></body>
  730.         </method>
  731.     </implementation>
  732.  
  733.     <handlers>
  734.         <handler event="popupshowing"><![CDATA[
  735.             if (this.popup.firstChild)
  736.                 return false;
  737.             var locator = this.getLocator();
  738.             var objects = locator.getLocationList();
  739.             if (!objects)
  740.             {
  741.                 this.setAttribute("label", "");
  742.                 this.setAttribute("location", null);
  743.                 return false;
  744.             }
  745.  
  746.             var groupNames = [];
  747.             var groups = {};
  748.  
  749.             var currentDescription = null;
  750.             if (this.repObject)
  751.                 currentDescription = locator.getObjectDescription(this.repObject);
  752.  
  753.             for (var i = 0; i < objects.length; ++i)
  754.             {
  755.                 var object = objects[i];
  756.                 var description = locator.getObjectDescription(object);
  757.                 if (!description)
  758.                     FBTrace.sysout("binding.xml popupshowing Fails" , object);
  759.                 var entry = {object: object, fileName: description.name};
  760.  
  761.                 if (currentDescription && currentDescription.name == description.name && currentDescription.path == description.path)
  762.                     entry.selected = true;
  763.  
  764.                 if (groups.hasOwnProperty(description.path))
  765.                     groups[description.path].push(entry);
  766.                 else
  767.                 {
  768.                     groups[description.path] = [entry];
  769.                     groupNames.push(description.path);
  770.                 }
  771.             }
  772.  
  773.             groupNames.sort();
  774.  
  775.             for (var i = 0; i < groupNames.length; ++i)
  776.             {
  777.                 var path = groupNames[i];
  778.                 var urls = groups[path];
  779.                 urls.sort(function(a, b) { return a.fileName < b.fileName ? -1 : 1; });
  780.  
  781.                 var menuHeader = FBL.createMenuHeader(this.popup, {label: path, nol10n: true});
  782.                 FBL.setClass(menuHeader, "fbURLMenuItem");
  783.  
  784.                 for (var j = 0; j < urls.length; ++j)
  785.                 {
  786.                     var menuInfo = {label: urls[j].fileName, nol10n: true};
  787.  
  788.                     if (urls[j].selected)
  789.                     {
  790.                         menuInfo.type = "checkbox";
  791.                         menuInfo.checked = true;
  792.                     }
  793.  
  794.                     var menuItem = FBL.createMenuItem(this.popup, menuInfo);
  795.                     menuItem.repObject = urls[j].object;
  796.                     FBL.setClass(menuItem, "fbURLMenuItem");
  797.                 }
  798.             }
  799.  
  800.         ]]></handler>
  801.  
  802.         <handler event="popupshown"><![CDATA[
  803.             // Weird, but this gets fired when the user clicks on a menuitem,
  804.             // which hiding the buttons again and resulting in jitters - let's avoid that.
  805.             if (!this._closed)
  806.                 return;
  807.  
  808.             // XXXjoe There is a bug in the <xul:autoscrollbox> code which,
  809.             // for reasons I don't grasp yet, never hides the scroll buttons
  810.             // after the first them they are shown - so we must do it ourselves
  811.             var scrollbox = document.getAnonymousElementByAttribute(
  812.                 this.popup, "class", "popup-internal-box");
  813.             if (scrollbox["_scrollButtonUp"])
  814.                 scrollbox["_scrollButtonUp"].collapsed = true;
  815.             if (scrollbox["_scrollButtonDown"])
  816.                 scrollbox["_scrollButtonDown"].collapsed = true;
  817.  
  818.             this._closed = false;
  819.  
  820.             this.searchString = "";
  821.             this.onkeypress = FBL.bind(this.onKeyPress, this);
  822.             window.addEventListener("keypress", this.onkeypress, true);
  823.         ]]></handler>
  824.  
  825.         <handler event="popuphidden"><![CDATA[
  826.             window.removeEventListener("keypress", this.onkeypress, true);
  827.             delete this.onkeypress;
  828.             delete this.searchString;
  829.  
  830.             FBL.eraseNode(this.popup);
  831.             this._closed = true;
  832.         ]]></handler>
  833.  
  834.         <handler event="command"><![CDATA[
  835.             var object = event.originalTarget.repObject;
  836.  
  837.             // Select after a timeout to increase teh snappy
  838.             setTimeout(FBL.bindFixed(function()
  839.             {
  840.                 this.selectObject(object);
  841.             }, this));
  842.         ]]></handler>
  843.  
  844.         <handler event="mouseover"><![CDATA[
  845.             var object = Firebug.getRepObject(event.target);
  846.             if (object)
  847.             {
  848.                 var locator = this.getLocator();
  849.                 event.target.setAttribute('tooltiptext', locator.getObjectLocation(object));
  850.             }
  851.  
  852.             return;
  853.         ]]></handler>
  854.     </handlers>
  855. </binding>
  856.  
  857. <binding id="searchBox">
  858.     <content sizetopopup="none">
  859.         <xul:textbox type="autocomplete" anonid="searchBox"
  860.                 rows="1" label="search.Firebug_Search" class="fbsearch-textbox" />
  861.         <xul:panel id="fbSearchOptionsPanel" norestorefocus="true" noautofocus="true" ignorekeys="true">
  862.             <xul:vbox>
  863.               <xul:box anonid="startPanelFocus" class="panelFocusBound" onfocus="startFocusHandler()"  />
  864.               <xul:vbox anonid="searchOptionsList"/>
  865.               <xul:hbox pack="center" align="center">
  866.                   <xul:button anonid="searchPrev" class="fbsearch-options-buttons" label="search.Previous" oncommand="searchPrev()" />
  867.                   <xul:button anonid="searchNext" class="fbsearch-options-buttons" label="search.Next" oncommand="searchNext()"/>
  868.               </xul:hbox>
  869.               <xul:box anonid="endPanelFocus" class="panelFocusBound" onfocus="endFocusHandler()" />
  870.             </xul:vbox>
  871.         </xul:panel>
  872.         <xul:box anonid="endTextFocus" class="panelFocusBound" onfocus="endTextFocusHandler()" />
  873.     </content>
  874.  
  875.     <implementation>
  876.         <constructor><![CDATA[
  877.             var searchBox = document.getAnonymousElementByAttribute(this, "anonid", "searchBox"),
  878.                 searchPrev = document.getAnonymousElementByAttribute(this, "anonid", "searchPrev"),
  879.                 searchNext = document.getAnonymousElementByAttribute(this, "anonid", "searchNext"),
  880.                 optionsPopup = document.getElementById("fbSearchOptionsPanel");
  881.             FBL.internationalize(searchBox, "label");
  882.             FBL.internationalize(searchPrev, "label");
  883.             FBL.internationalize(searchNext, "label");
  884.  
  885.             searchBox.addEventListener("focus", FBL.bind(this.focusHandler, this), true);
  886.             optionsPopup.addEventListener("focus", FBL.bind(this.panelFocusHandler, this), true);
  887.         ]]></constructor>
  888.         <property name="value">
  889.             <xbl:getter><![CDATA[
  890.                 var searchBox = document.getAnonymousElementByAttribute(this, "anonid", "searchBox");
  891.                 return searchBox.value;
  892.             ]]></xbl:getter>
  893.             <xbl:setter><![CDATA[
  894.                 var searchBox = document.getAnonymousElementByAttribute(this, "anonid", "searchBox");
  895.                 searchBox.value = val;
  896.             ]]></xbl:setter>
  897.         </property>
  898.         <property name="optionsShown">
  899.             <xbl:getter><![CDATA[
  900.                 var optionsPopup = document.getElementById("fbSearchOptionsPanel");
  901.                 return optionsPopup.state == "open";
  902.             ]]></xbl:getter>
  903.         </property>
  904.  
  905.         <!-- Flag indicating that the child of the panel has or just had focus -->
  906.         <field name="panelHasFocus" />
  907.         <field name="blurTimeout" />
  908.  
  909.         <method name="updateOptions">
  910.             <parameter name="menuItems" />
  911.             <body><![CDATA[
  912.                 var searchOptions = document.getAnonymousElementByAttribute(this, "anonid", "searchOptionsList");
  913.                 FBL.eraseNode(searchOptions);
  914.  
  915.                 if (menuItems)
  916.                 {
  917.                     for (var i=0; i<menuItems.length; i++)
  918.                     {
  919.                         var checkbox = document.createElement("checkbox");
  920.                         checkbox.className = "fbsearch-options-label";
  921.                         FBL.setItemIntoElement(checkbox, menuItems[i]);
  922.  
  923.                         searchOptions.appendChild(checkbox);
  924.                     }
  925.                 }
  926.             ]]></body>
  927.         </method>
  928.         <method name="showOptions">
  929.             <body><![CDATA[
  930.                 var optionsPopup = document.getElementById("fbSearchOptionsPanel"),
  931.                     searchBox = document.getAnonymousElementByAttribute(this, "anonid", "searchBox"),
  932.                     position = (Firebug.getPlacement() == "detached") ? "after_end" : "before_end";
  933.                 optionsPopup.setAttribute("position", position);
  934.                 optionsPopup.openPopup(this, position, 0, 0, false, false);
  935.  
  936.                 clearTimeout(this.blurTimeout);
  937.                 delete this.blurTimeout;
  938.             ]]></body>
  939.         </method>
  940.         <method name="hideOptions">
  941.             <body><![CDATA[
  942.                 var optionsPopup = document.getElementById("fbSearchOptionsPanel");
  943.                 optionsPopup.hidePopup();
  944.  
  945.                 clearTimeout(this.blurTimeout);
  946.                 delete this.blurTimeout;
  947.             ]]></body>
  948.         </method>
  949.         <method name="searchNext">
  950.             <body><![CDATA[
  951.                 Firebug.Search.searchNext(FirebugContext);
  952.             ]]></body>
  953.         </method>
  954.         <method name="searchPrev">
  955.             <body><![CDATA[
  956.                 Firebug.Search.searchPrev(FirebugContext);
  957.             ]]></body>
  958.         </method>
  959.  
  960.         <method name="focus">
  961.             <body><![CDATA[
  962.                 var searchBox = document.getAnonymousElementByAttribute(this, "anonid", "searchBox");
  963.                 searchBox.focus();
  964.             ]]></body>
  965.         </method>
  966.         <method name="select">
  967.             <body><![CDATA[
  968.                 var searchBox = document.getAnonymousElementByAttribute(this, "anonid", "searchBox");
  969.                 searchBox.select();
  970.             ]]></body>
  971.         </method>
  972.  
  973.         <!--
  974.         Focus management handlers. These must be defined as methods and registered
  975.         using addEventListener or attribute registration as XBL handlers do not
  976.         appear to allow access to anonymous event targets when capturing.
  977.          -->
  978.         <method name="focusHandler">
  979.             <parameter name="event" />
  980.             <body><![CDATA[
  981.                 var target = event.target;
  982.                 clearTimeout(this.blurTimeout);
  983.                 delete this.blurTimeout;
  984.  
  985.                 if (!FBL.hasClass(target, "panelFocusBound")) {
  986.                     this.showOptions();
  987.                 }
  988.             ]]></body>
  989.         </method>
  990.         <method name="panelFocusHandler">
  991.             <parameter name="event" />
  992.             <body><![CDATA[
  993.                 this.focusHandler(event);
  994.  
  995.                 if (!FBL.hasClass(event.target, "panelFocusBound")) {
  996.                     this.panelHasFocus = true;
  997.                 }
  998.             ]]></body>
  999.         </method>
  1000.         <method name="endTextFocusHandler">
  1001.             <body><![CDATA[
  1002.                 clearTimeout(this.blurTimeout);
  1003.                 delete this.blurTimeout;
  1004.  
  1005.                 if (this.panelHasFocus) {
  1006.                     // The user has just tabbed out of the panel
  1007.                     document.commandDispatcher.advanceFocus();
  1008.                     this.panelHasFocus = false;
  1009.                 } else if (this.optionsShown) {
  1010.                     // The user has just tabbed out of the search box (and into the panel)
  1011.                     var optionsPopup = document.getElementById("fbSearchOptionsPanel");
  1012.                     document.commandDispatcher.advanceFocusIntoSubtree(optionsPopup);
  1013.                 } else {
  1014.                     // The user has just reverse tabbed from the next tab target
  1015.                     this.showOptions();
  1016.  
  1017.                     var searchNext = document.getAnonymousElementByAttribute(this, "anonid", "searchNext");
  1018.                     setTimeout(function() { searchNext.focus(); }, 0);
  1019.                     this.panelHasFocus = true;
  1020.                 }
  1021.             ]]></body>
  1022.         </method>
  1023.         <method name="startFocusHandler">
  1024.             <body><![CDATA[
  1025.                 if (this.panelHasFocus) {
  1026.                     // The user has shift-tabbed out of the panel
  1027.                     var searchBox = document.getAnonymousElementByAttribute(this, "anonid", "searchBox")
  1028.                     searchBox.focus();
  1029.                 } else {
  1030.                     // The user has just tabbed into the panel
  1031.                     document.commandDispatcher.advanceFocus();
  1032.                     this.panelHasFocus = true;
  1033.                 }
  1034.             ]]></body>
  1035.         </method>
  1036.         <method name="endFocusHandler">
  1037.             <body><![CDATA[
  1038.                 // The user has just tabbed out of the panel
  1039.                 this.hideOptions();
  1040.  
  1041.                 var endTextFocus = document.getAnonymousElementByAttribute(this, "anonid", "endTextFocus");
  1042.                 endTextFocus.focus();
  1043.             ]]></body>
  1044.         </method>
  1045.     </implementation>
  1046.     <handlers>
  1047.             <handler event="keypress"><![CDATA[
  1048.             if (event.keyCode ==  KeyEvent.DOM_VK_RETURN)
  1049.             {
  1050.                 if (FBL.isShift(event))
  1051.                     this.searchPrev();
  1052.                 else if (FBL.isControl(event))
  1053.                     FBL.dispatch([Firebug.A11yModel], 'moveToSearchMatch');
  1054.                 else
  1055.                     this.searchNext();
  1056.             }
  1057.             else
  1058.                 return;
  1059.  
  1060.             FBL.cancelEvent(event);
  1061.         ]]></handler>
  1062.  
  1063.         <handler event="input"><![CDATA[
  1064.             Firebug.Search.update(FirebugContext);
  1065.         ]]></handler>
  1066.  
  1067.         <handler event="popupshowing"><![CDATA[
  1068.             this.panelHasFocus = false;
  1069.         ]]></handler>
  1070.         <handler event="blur" phase="capturing"><![CDATA[
  1071.             this.blurTimeout = this.blurTimeout || setTimeout(function() {
  1072.                 hideOptions();
  1073.             }, 0);
  1074.         ]]></handler>
  1075.     </handlers>
  1076. </binding>
  1077.  
  1078. <binding id="commandLine" extends="chrome://global/content/bindings/textbox.xml#textarea">
  1079.     <handlers>
  1080.         <handler event="input"><![CDATA[
  1081.             Firebug.CommandLine.update(FirebugContext);
  1082.         ]]></handler>
  1083.  
  1084.         <handler event="overflow"><![CDATA[
  1085.             if (window.Firebug)
  1086.                 Firebug.CommandLine.checkOverflow(FirebugContext);
  1087.         ]]></handler>
  1088.  
  1089.         <handler event="keypress" keycode="VK_TAB"><![CDATA[
  1090.             if (this.value == "")
  1091.             {
  1092.                 return;
  1093.             }
  1094.             Firebug.CommandLine.complete(FirebugContext, FBL.isShift(event));
  1095.             event.preventDefault();
  1096.         ]]></handler>
  1097.  
  1098.         <handler event="keypress" keycode="VK_RETURN" modifiers="" preventdefault="true"><![CDATA[
  1099.             Firebug.CommandLine.enter(FirebugContext);
  1100.         ]]></handler>
  1101.  
  1102.         <handler event="keypress" keycode="VK_RETURN" modifiers="meta" preventdefault="true"><![CDATA[
  1103.             Firebug.CommandLine.enterMenu(FirebugContext);
  1104.         ]]></handler>
  1105.  
  1106.         <handler event="keypress" keycode="VK_RETURN" modifiers="shift" preventdefault="true"><![CDATA[
  1107.             Firebug.CommandLine.enterInspect(FirebugContext);
  1108.         ]]></handler>
  1109.  
  1110.         <handler event="keypress" keycode="VK_UP" preventdefault="true"><![CDATA[
  1111.             Firebug.CommandLine.cycleCommandHistory(FirebugContext, -1);
  1112.         ]]></handler>
  1113.  
  1114.         <handler event="keypress" keycode="VK_DOWN" preventdefault="true"><![CDATA[
  1115.             Firebug.CommandLine.cycleCommandHistory(FirebugContext, 1);
  1116.         ]]></handler>
  1117.  
  1118.         <handler event="keypress" keycode="VK_ESCAPE" preventdefault="true"><![CDATA[
  1119.             Firebug.CommandLine.cancel(FirebugContext);
  1120.         ]]></handler>
  1121.     </handlers>
  1122. </binding>
  1123.  
  1124. <binding id="largeCommandLine" extends="chrome://global/content/bindings/textbox.xml#textarea">
  1125.     <handlers>
  1126.         <handler event="input"><![CDATA[
  1127.             Firebug.CommandLine.update(FirebugContext);
  1128.         ]]></handler>
  1129.  
  1130.         <handler event="keypress" keycode="VK_TAB"><![CDATA[
  1131.             var input = document.getAnonymousElementByAttribute(this, "anonid", "input");
  1132.             FBL.insertTextIntoElement(input, Firebug.Editor.tabCharacter);
  1133.             event.preventDefault();
  1134.         ]]></handler>
  1135.  
  1136.         <handler event="keypress" keycode="VK_RETURN" modifiers="meta" preventdefault="true"><![CDATA[
  1137.             Firebug.CommandLine.enter(FirebugContext);
  1138.         ]]></handler>
  1139.  
  1140.         <handler event="keypress" keycode="VK_RETURN" modifiers="control" preventdefault="true"><![CDATA[
  1141.             Firebug.CommandLine.enter(FirebugContext);
  1142.         ]]></handler>
  1143.  
  1144.         <handler event="keypress" keycode="VK_ESCAPE" preventdefault="true"><![CDATA[
  1145.             Firebug.CommandLine.cancel(FirebugContext);
  1146.         ]]></handler>
  1147.     </handlers>
  1148. </binding>
  1149.  
  1150. </bindings>
  1151.